<?php


namespace app\api\controller\v25;


use app\api\controller\v13\Auth2;
use app\common\lib\Aes;
use app\common\lib\exception\ApiException;
use app\common\lib\IAuth;
use app\common\lib\SensorsData;
use app\common\lib\Util;
use app\common\model\User;
use app\common\model\UserPush;
use think\Cache;
use think\Db;
use think\Exception;
use think\Log;
use think\response\Json;

class Login extends Auth2
{

    /**
     * @title 绑定手机号失败后快捷登录接口
     * @method POST
     * @return Json
     * @throws ApiException
     */
    public function telTokenLogin()
    {
        #神策打点 5   登录成功
        $sensorsTrackData = [
            'is_register' => false,
            'login_type' => '绑定失败手机号快捷登录',// 手机号、微信、QQ、微博、AppleID、手机号一键登录
            'is_temporary' => false,// 三方登录时，需要设置这个属性
            'is_success' => true,
            'failed_reson' => '',
        ];
        if (!$this->request->isPost())
        {
            return show(config('code.error'), '未知操作');
        }
        $distinctId = $this->request->header('distinct-id', '');

        $tel = input('tel/s', '');
        $loginToken = input('login_token/s', '');
        $areaCode = input('area_code/d', 86);
        $time = $this->request->time();
        $ip = $this->request->ip();
        $appConfig = config('app');
        $mobileTel = $areaCode === 86 ? $tel : $areaCode . '-' . $tel;
        $loginTokenCache = Cache::get('bindTel:loginToken:' . $mobileTel, '');
        if (empty($loginToken) || $loginToken !== $loginTokenCache)
        {
            return show(405, '登录失败');
        }

        // 手机号不可注册
        $user = $this->CheckUserTel($tel, $areaCode);

        if (!$user)
        {
            return show(405, '登录失败');
        }

        // 生成token  和 token到期时间
        $token = IAuth::setAppLoginToken($tel);
        $data = [
            'token' => $token,
            'token_expire' => strtotime("+" . $appConfig['login_time_out_day'] . " days"),
        ];
        $UserModel = new User();
        //判断用户是否绑定准了号
        $UserModel->check_uen($user);

        $nickname = preg_replace('/(1[3456789]{1}[0-9])[0-9]{4}([0-9]{4})/i', '$1****$2', $tel);
        $isRegist = false;
        // 该用户是否正常  forbidden==1 禁止登录
        if ($user['forbidden'] == 0)
        {
            // 已过期重新生成access_token
            if ($time > $user['token_expire'] || !in_array($tel, $appConfig['mobile']))
            {
                $mobileTel = $areaCode === 86 ? $tel : $areaCode . '-' . $tel;
                $UserModel->save($data, ['tel' => $mobileTel]);
            } else
            {
                $token = $user['token'];
            }
//            $UserModel->save($data, ['tel' => $tel]);
            if (!$user['nickname'])
            {
                try
                {
                    Db::table('app_user')->where('tel', $tel)
                        ->update(['nickname' => $nickname]);
                }
                catch (Exception $e)
                {
                    Log::write('手机验证码登陆时初始化用户昵称失败' . $e->getMessage(), true);
                }
            }
        } elseif ($user['forbidden'] == 1)
        {
            if ($distinctId)
            {
                $sensorsTrackData['is_success'] = false;
                $sensorsTrackData['failed_reson'] = '该账号禁止登录';
                SensorsData::track($distinctId, false, 'LoginSuccess', $sensorsTrackData);
            }
            return show(config('code.error'), '该账号禁止登录');
        }

        $id = (int)($user['id']);

        if (!$isRegist)
        {
            $userPush = (new UserPush())->getUserRegid($id);
            $calendarBirthdayStatus = (int)($userPush['calendar_birthday_status'] ?? 0);
            $recodePrivateStatus = (int)($userPush['recode_private_status'] ?? 0);
            $isLoginRecord = 1;
        } else
        {
            $calendarBirthdayStatus = 1;
            $recodePrivateStatus = 1;
            $isLoginRecord = (int)($user['is_login_record'] ?? 1);  // 是否记录设备登陆历史 1=>记录，2=>不记录
        }

        // 记录登陆设备日志
        Util::loginRecordSave($id, 4, $isLoginRecord, $ip);

        if (isset($user['young_pwd']))
        {
            $isYoung = $user['young_pwd'] ? true : false;
        } else
        {
            $isYoung = false;
        }

        $result = [
            'id' => $id,
            'has_self_recode' => $user['has_self_recode'],
            'user_access_token' => (new Aes())->encryptWithOpenssl($token . "||" . $user['id']),
            'uc_id' => $user['uc_id'],
            'calendar_birthday_status' => $calendarBirthdayStatus ?: 1,   // 在天象日历中展示生日信息
            'recode_private_status' => $recodePrivateStatus ?: 1,   // 在星盘中展示档案详细信息
            'has_bind_tel' => 1,     // 是否绑定了手机号 1绑定了 0未绑定
            'is_young_model' => $isYoung ? 1 : 2,
        ];
        // 记录登陆日志
        Db::table('app_login_log')->insertGetId([
            'uid' => $id,
            'login_time' => $time,
            'login_type' => 4,
            'login_ip' => $ip,
        ]);
        if ($distinctId)
        {
            // 神策打点，用户关联
            SensorsData::signup($id, $distinctId);
            SensorsData::track($id, true, 'LoginSuccess', $sensorsTrackData);
        }

        Cache::rm('bindTel:loginToken:' . $mobileTel);
        return show(config('code.success'), 'ok', $result);
    }

    /**
     * 检测手机号格式，不可注册
     * @param $tel
     * @param int $areaCode 手机区号
     * @return array
     * @throws ApiException
     */
    public function CheckUserTel($tel, $areaCode = 86)
    {
        // 手机号是否存在
        if (!Util::telRuleCheck($tel, $areaCode))
        {
            Log::write($areaCode . $tel . '手机号错误', 'error');
            $distinctId = $this->request->header('distinct-id', '');
            if ($distinctId)
            {
                #神策打点 5   登录成功
                $sensorsTrackData = [
                    'is_register' => false,
                    'login_type' => '手机号',// 手机号、微信、QQ、微博、AppleID、手机号一键登录
                    'is_temporary' => false,// 三方登录时，需要设置这个属性
                    'is_success' => false,
                    'failed_reson' => '手机号错误',
                ];
                SensorsData::track($distinctId, false, 'LoginSuccess', $sensorsTrackData);
            }

            throw new ApiException('手机号错误', 200, 0);
        }
        //判断手机号是否注册过
        try
        {
            $tel = $areaCode === 86 ? $tel : $areaCode . '-' . $tel;

            $user = (new \app\common\cachemodel\User())
                ->field('id,forbidden,has_self_recode,password,young_pwd,nickname,uc_id,avatar,token_expire,token,uen,is_login_record')
                ->where(['tel' => $tel])->findOrFail()->toArray();
        }
        catch (Exception $e)
        {
            $user = [];
            // throw new ApiException('手机号未注册，请用三方登录', 200, 409);
        }
        return $user;
    }
}
